/*
 * @Author: li2022 liqing@linkon.me
 * @Date: 2022-10-28 10:04:11
 * @LastEditors: dazy916 dazy916@126.com
 * @LastEditTime: 2025-08-13 17:06:49
 * @FilePath: \admin-operate\src\router\http.js
 * @Description: 增强版HTTP请求封装，支持Blob音频流上传和请求中断
 */
import request from "./request";

// 存储所有活动的取消令牌
const activeCancelTokens = new Map();

const http = {
    /**
     * GET请求
     * @param {string} url 请求地址
     * @param {object} params 查询参数
     * @param {boolean} blob 是否返回Blob数据
     * @param {string} requestId 请求唯一标识(用于取消)
     */
    get(url, params, blob = false, requestId = null) {
        const config = {
            method: "get",
            url: url,
            responseType: blob ? "blob" : "json"
        };
        if (params) config.params = params;

        // 添加取消令牌
        if (requestId) {
            const source = axios.CancelToken.source();
            activeCancelTokens.set(requestId, source);
            config.cancelToken = source.token;
        }

        return request(config).finally(() => {
            if (requestId) activeCancelTokens.delete(requestId);
        });
    },

    /**
     * POST请求（增强版）
     * @param {string} url 请求地址
     * @param {object|FormData|Blob} data 请求数据
     * @param {object} options 扩展选项 {
     *   headers: 自定义headers,
     *   responseType: 响应类型,
     *   formData: 是否自动转换为FormData,
     *   requestId: 请求唯一标识(用于取消)
     * }
     */
    post(url, data, options = {}) {
        const config = {
            method: "post",
            url: url,
            headers: options.headers || {},
            responseType: options.responseType || "json"
        };

        // 添加取消令牌
        if (options.requestId) {
            const source = axios.CancelToken.source();
            activeCancelTokens.set(options.requestId, source);
            config.cancelToken = source.token;
        }

        // 处理Blob或File类型数据
        if (data instanceof Blob || data instanceof File) {
            const formData = new FormData();
            formData.append("file", data);
            formData.append("filename", data.name || "audio.mp3");
            config.data = formData;

            // 自动设置Content-Type
            if (!config.headers['Content-Type']) {
                config.headers['Content-Type'] = 'multipart/form-data';
            }
        }
        // 处理普通对象且需要FormData的情况
        else if (options.formData && typeof data === 'object') {
            const formData = new FormData();
            Object.keys(data).forEach(key => {
                formData.append(key, data[key]);
            });
            config.data = formData;

            if (!config.headers['Content-Type']) {
                config.headers['Content-Type'] = 'multipart/form-data';
            }
        }
        // 普通JSON数据
        else {
            config.data = data;
            if (!config.headers['Content-Type']) {
                config.headers['Content-Type'] = 'application/json';
            }
        }

        return request(config).finally(() => {
            if (options.requestId) activeCancelTokens.delete(options.requestId);
        });
    },

    /**
     * 专门用于音频上传的方法
     * @param {string} url 上传地址
     * @param {Blob|File} audioBlob 音频数据
     * @param {object} extraFields 额外表单字段
     * @param {string} requestId 请求唯一标识(用于取消)
     */
    uploadAudio(url, audioBlob, extraFields = {}, requestId = null) {
        const formData = new FormData();
        formData.append("file", audioBlob, "recording.mp3");

        // 添加额外字段
        Object.keys(extraFields).forEach(key => {
            formData.append(key, extraFields[key]);
        });

        return this.post(url, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            },
            responseType: 'json',
            requestId: requestId
        });
    },
    /**
 * 专门用于音频上传的方法
 * @param {string} url 上传地址
 * @param {Blob|File} audioBlob 音频数据
 * @param {object} extraFields 额外表单字段
 * @param {string} requestId 请求唯一标识(用于取消)
 */
    uploadImg(url, audioBlob, extraFields = {}, requestId = null) {
        const formData = new FormData();
        formData.append("file", audioBlob);

        // 添加额外字段
        Object.keys(extraFields).forEach(key => {
            formData.append(key, extraFields[key]);
        });

        return this.post(url, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            },
            responseType: 'json',
            requestId: requestId
        });
        },

    /**
     * 取消指定请求
     * @param {string} requestId 要取消的请求ID
     * @param {string} reason 取消原因
     */
    cancelRequest(requestId, reason = '请求被手动取消') {
        if (activeCancelTokens.has(requestId)) {
            activeCancelTokens.get(requestId).cancel(reason);
            activeCancelTokens.delete(requestId);
        }
    },

    /**
     * 取消所有未完成的请求
     * @param {string} reason 取消原因
     */
    cancelAllRequests(reason = '所有请求被取消') {
        activeCancelTokens.forEach((source, requestId) => {
            source.cancel(reason);
            activeCancelTokens.delete(requestId);
        });
    }
};

export default http;